using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using King.Engine.Content;

namespace King.Engine.Core
{
    /// <summary>
    /// Extension to the XNA Game.
    /// This manages the setup and loading process for the game.
    /// This also handles the update and draw cycles for Activities and Input
    /// </summary>
    public class Game : Microsoft.Xna.Framework.Game
    {

        #region Fields

        private static Game _currentGame;

        private GraphicsDeviceManager _graphics;
        private SpriteBatch _spriteBatch;
        private Color _backColor;
        private string _contentTableFile;

        #endregion


        #region Constructor

        private Game(string contentTableFile, Color backColor)
        {
            _graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            _backColor = backColor;
            _contentTableFile = contentTableFile;
        }

        #endregion


        #region Public Methods


        /// <summary>
        /// Create a new game, starting with the given Activity type.
        /// This will load content from the file, "table.txt"
        /// </summary>
        /// <typeparam name="T">Type of the first activity</typeparam>
        public static void Run<T>() where T : Activity, new()
        {
            Run<T>("table.txt");
        }

        /// <summary>
        /// Create a new game, starting with the given Activity type.
        /// </summary>
        /// <typeparam name="T">Type of the first activity</typeparam>
        /// <param name="contentTablefile">Location of the content table file</param>
        public static void Run<T>(string contentTablefile) where T : Activity, new()
        {
            Run<T>(contentTablefile, Color.Black);
        }

        /// <summary>
        /// Create a new game, starting with the given Activity type.
        /// </summary>
        /// <typeparam name="T">Type of the first activity</typeparam>
        /// <param name="contentTablefile">Location of the content table file</param>
        /// <param name="backgroundColor">The background color of the world</param>
        public static void Run<T>(string contentTablefile, Color backgroundColor) where T:Activity, new()
        {
            ActivityManager.SetActivity<T>();

            _currentGame = new Game(contentTablefile, backgroundColor);
            _currentGame.Run();
        }

        /// <summary>
        /// Exit the current game
        /// </summary>
        public static void ExitGame()
        {
            _currentGame.Exit();
        }

        #endregion


        #region Protected Methods

        protected sealed override void Initialize()
        {
            Screen.Initialize(_graphics);
            Input.Initialize();
            base.Initialize();
        }

        protected sealed override void LoadContent()
        {
            _spriteBatch = new SpriteBatch(GraphicsDevice);

            ContentLoader.Load(Content, _contentTableFile);

            base.LoadContent();
        }

        protected sealed override void Update(GameTime gameTime)
        {
            Input.Update();
            ActivityManager.Update(gameTime);
            base.Update(gameTime);
        }

        protected sealed override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(_backColor);

            Screen.BeginSpriteBatch(_spriteBatch);
            ActivityManager.Draw();
            Screen.EndSpriteBatch();

            base.Draw(gameTime);
        }

        #endregion

    }
}
